package biz.datalk.industrialland.common.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * spring工具类
 *
 * @author tarofang@163.com
 * @date 2019年08月11日
 */
@SuppressWarnings({"WeakerAccess", "unused"})
@Component
public class SpringContextUtils implements ApplicationContextAware {

    /** 上下文对象实例 */
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }

    /**
     * 获取applicationContext
     *
     * @return {@link ApplicationContext}
     *
     * @author tarofang@163.com
     * @date 2019年08月11日
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 获取 HttpServletRequest
     *
     * @return {@link HttpServletRequest}
     *
     * @author tarofang@163.com
     * @date 2019年08月11日
     */
    public static HttpServletRequest getHttpServletRequest() {
        // return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
    }

    public static HttpServletResponse getHttpServletResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse();
    }

    public static String getDomain() {
        HttpServletRequest request = getHttpServletRequest();
        StringBuffer url = request.getRequestURL();
        return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
    }

    public static String getOrigin() {
        HttpServletRequest request = getHttpServletRequest();
        return request.getHeader("Origin");
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name bean的名字
     *
     * @return 指定名字的Bean
     *
     * @author tarofang@163.com
     * @date 2019年08月11日
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz 指定类型的Class
     * @param <T>   指定类型
     *
     * @return 指定类型的Bean
     *
     * @author tarofang@163.com
     * @date 2019年08月11日
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name  bean的名字
     * @param clazz 指定类型的Class
     * @param <T>   指定类型
     *
     * @return 指定名字指定类型的 Bean
     *
     * @author tarofang@163.com
     * @date 2019年08月11日
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

    public static String getActiveProfile() {
        return SpringContextUtils.applicationContext.getEnvironment().getActiveProfiles()[0];
    }

    public static <T> T getProperty(String propertyName, Class<T> clazz, T defaultVal) {
        Environment environment = SpringContextUtils.applicationContext.getEnvironment();
        return environment.getProperty(propertyName, clazz, defaultVal);
    }

    /**
     * 获取请求对应的 spring的 处理方法
     *
     * @author tarofang@163.com
     * @date 2020年04月16日
     *
     * @param request {@link HttpServletRequest}
     * @return {@link HandlerMethod}
     */
    public static HandlerMethod getRequestHandlerMethod(HttpServletRequest request) {
        //try {
        //    HandlerExecutionChain handler = requestMappingHandlerMapping.getHandler(request);
        //    Object handler1 = handler.getHandler();
        //    System.out.println(handler1.getClass().getName());
        //} catch (Exception e) {
        //}

        RequestMappingHandlerMapping requestMappingHandlerMapping = getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();
        RequestMappingInfo requestMappingInfo, matchingCondition;
        for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethodMap.entrySet()) {
            requestMappingInfo = entry.getKey();
            matchingCondition = requestMappingInfo.getMatchingCondition(request);
            if (requestMappingInfo.equals(matchingCondition)) {
                return entry.getValue();
            }
        }

        return null;
    }
}
